package com.newtribe.access;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

public class BridgeLayer {
	
    private static final int VERSION=0xfe;

    private static final int BER_STRING=4;
    
    private static final int AUTH_RESPONSE=2;


	protected Socket sock ;
    private DataInputStream in=null;
    private DataOutputStream out=null;
	public BridgeLayer(Socket socket) {
		this.sock =socket;
	}
	public void init()throws Exception {
	
		this.in =new DataInputStream(this.sock.getInputStream());
		this.out =new DataOutputStream(this.sock.getOutputStream());
	}
	public static void main(String[] sa)throws Exception{

		Socket socket =new Socket ("studio",9000) ;
		BridgeLayer layer =new BridgeLayer(socket) ;
		layer.init();
		layer.sendAuthInfo();
	}
	
	public void send(Packet packet) throws Exception {
		int length =packet.getSize() ;
		byte[] buff =new byte[length];
		packet.setPosition(0);
		// 4 byte head 
		packet.write8(VERSION);
		packet.skipBytes(1) ;
		packet.write16(length) ;
		packet.copyToByteArray(buff, 0 , length);
		
		////////
		
		
		///
		out.write(buff) ;
		out.flush();
		System.out.println();
		//
		
	}
	public void sendAuthInfo() throws Exception{
		Packet packet =new Packet(512) ;
		packet.setPosition(4);
		packet.write8(BER_STRING) ;
		String authstr ="fuwei;123456";
		packet.write16(authstr.length()) ;
		packet.write(authstr.getBytes());
		packet.markEnd();
		send(packet) ;
		
	}
	/**
	 * 
	 * @return user name and password info in a stirng .
	 * @throws Exception
	 */
	public String getAuthInfo()throws Exception {
		Packet packet =receive() ;
		if (packet ==null)
			return null ;
		packet.skipBytes(4) ;
		int type =packet.read8() ;
		if (type !=BER_STRING )
			return null ;
		int len =packet.read16();
		String authInfo =packet.readString(len) ;
		return authInfo ;
	}
	
	
	public void sendAuthResponse() throws Exception{
		Packet packet =new Packet(512) ;
		packet.setPosition(4);
		packet.write8(AUTH_RESPONSE) ;
		String sessionid =String.valueOf(System.currentTimeMillis());
		System.out.println("''''''''''''''' user session key:"+sessionid);
		packet.write16(sessionid.length()) ;
		packet.write(sessionid.getBytes());
		packet.markEnd();
		send(packet) ;
		
	}
	/**
	 * 
	 * @return user session id 
	 * @throws Exception
	 */
	public String getAuthResponse()throws Exception {
		Packet packet =receive() ;
		if (packet ==null)
			return null ;
		packet.skipBytes(4) ;
		int type =packet.read8() ;
		if (type !=AUTH_RESPONSE )
			return null ;
		int len =packet.read16();
		String sessionid =packet.readString(len) ;
		return sessionid ;
	}
	public Packet receive() throws Exception {
		Packet head =tcp_recv(null,4);
		int version =head.read8() ;
		head.skipBytes(1) ;
		int length =head.read16();
		if (version ==VERSION){
			Packet packet = tcp_recv(head ,length -4) ;
			return packet ;
		}else {
			if (this.sock !=null)
			this.sock.close() ;
		}
		return null;
		
		
	}
	
	Packet tcp_recv(Packet packet ,int length)throws Exception {
		byte[] bf =new byte[length] ;
		in.readFully(bf,0,length) ;
		
		if (packet ==null ){
			packet =new Packet(length) ;
			packet.write(bf) ;
		}else {
			Packet packet2 =new Packet(packet.getSize()+length) ;
			byte[] packet_content =new byte[packet.getSize()] ;
			packet.copyToByteArray(packet_content, 0, packet.getSize());
			packet2.write(packet_content) ;
			packet2.write(bf) ;
			packet =packet2 ;
			
		}
		packet.markEnd();
		packet.flip();
		return packet ;
	}

}
